package com.demo.web.core;

import com.demo.core.BeanDefinition;
import com.demo.web.annotation.Controller;
import com.demo.web.annotation.RequestMapping;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class WebFactory {
    private Map<String,Object> container ;
    private Set<BeanDefinition> beanDefinitions;
    private Set<BeanDefinition> webBeanDefinitions;
    private Map<String,Object> webPathWithBean=new HashMap<>(); //存储 path: bean; 每一个路径，必须匹配一个对象
    private Map<String,Object> webPathWithMethod = new HashMap<>();//存储 path: method; 每一个路径，必须匹配一个 方法对象

    public WebFactory(Map<String,Object> container,Set<BeanDefinition> beanDefinitions) {
        this.beanDefinitions = beanDefinitions;
        this.container = container;
        webBeanDefinitions = getWebBeanDefinition();
        this.computeWebPathInfo();
    }
    // 从所有的bean定义中 把 web层面的bean，例如@Controller注解标注的
    public Set<BeanDefinition> getWebBeanDefinition(){
        Set<BeanDefinition> beans = new HashSet<>();
        this.beanDefinitions.forEach(def->{
            if(def.getBeanClass().isAnnotationPresent(Controller.class)){
                beans.add(def);
            }
        });
        return beans;
    }

    /**
     * 这里的任务是把 @Controller对象中的RequestMapping中的值 提取出来，组成 完整的uri 和对象map集合
     *
     */
    public void computeWebPathInfo(){
        webBeanDefinitions.forEach(webDef->{ // 都有@Controller注解的类
            String beanName = webDef.getBeanName();
            Class beanClass = webDef.getBeanClass();
            boolean flag = beanClass.isAnnotationPresent(RequestMapping.class);
            if(flag){ //存在 父uri
                String parentPath=null ;
                //1,得到类上的路径
                RequestMapping requestMapping1 = (RequestMapping) beanClass.getAnnotation(RequestMapping.class);
                parentPath = requestMapping1.value();
//                2，得到方法上的路径，进行拼接，并将其加入 响应的map中
                for (Method declaredMethod : beanClass.getDeclaredMethods()) {
                    Annotation methodAnnotation = declaredMethod.getAnnotation(RequestMapping.class);
                    if(methodAnnotation!=null){
                        String methodPath = "/"+((RequestMapping)methodAnnotation).value();
                        //此时， map中要添加数据， 添加对象map，添加方法map
                        String fullMethodPath = parentPath+methodPath;
                        this.webPathWithBean.put(fullMethodPath,container.get(beanName));
                        this.webPathWithMethod.put(fullMethodPath,declaredMethod);
                    }
                }
            }else { // 只存在 子 uri

                for (Method declaredMethod : beanClass.getDeclaredMethods()) {
                    RequestMapping methodAnnotation = declaredMethod.getAnnotation(RequestMapping.class);
                    if(methodAnnotation!=null){
                        String methodPath = "/"+((RequestMapping)methodAnnotation).value();
                        //此时， map中要添加数据， 添加对象map，添加方法map
                        this.webPathWithBean.put(methodPath,container.get(beanName));
                        this.webPathWithMethod.put(methodPath,declaredMethod);
                    }
                }
            }


        });
    }




    public Set<BeanDefinition> getWebBeanDefinitions() {
        return webBeanDefinitions;
    }

    public Set<BeanDefinition> getBeanDefinitions() {
        return beanDefinitions;
    }

    public Map<String, Object> getWebPathWithBean() {
        return webPathWithBean;
    }

    public Map<String, Object> getWebPathWithMethod() {
        return webPathWithMethod;
    }
}
